import React from "react";
import BooleanComponent from "./components/Boolean";
import InputComponent from "./components/Input";
import DatePickerRangeComponent from "./components/DatePickerRange";
import DatePickerComponent from "./components/DatePicker";
import DoubleInputComponent from "./components/DoubleInput";
import SelectComponent from "./components/Select";
import ArrayInputComponent from "./components/ArrayInput";

import {
  isEmpty,
  isIP,
  isIPv4WithMask,
  isIPv6WithPrefix,
  isUndefined,
} from "@ct0/functions";
import type {
  NestFilterField,
  NestFilterFieldValue,
  NestFilterOperator,
} from "./type";

export default ConditionItemValue;

type Value = Array<NestFilterFieldValue>;

interface ConditionItemValueProps {
  field: NestFilterField;
  value: Value;
  operator: NestFilterOperator;
  showError?: boolean;
  disabled?: boolean;
  onChange: (v: Value) => void;
}

function getValueByType<V>(
  v: any,
  type: string | Array<string>,
  defaultValue: V | undefined
): V | undefined {
  return type.includes(typeof v) ? v : defaultValue;
}

function ConditionItemValue({
  field,
  value,
  operator,
  showError,
  disabled,
  onChange,
}: ConditionItemValueProps) {
  if (operator == "is null") {
    const v = getValueByType<boolean>(value[0], "boolean", undefined);
    const errmsg = showError && isEmpty(v) ? "字段必填" : undefined;
    return (
      <BooleanComponent
        key={field.key}
        disabled={disabled}
        errmsg={errmsg}
        value={v}
        onChange={(v) => onChange([v])}
      />
    );
  }

  if (field.type == "string") {
    if (field.component == "input") {
      const v = getValueByType(value[0], "string", "");
      const errmsg = showError && !v ? "字段必填" : undefined;

      return (
        <InputComponent
          key={field.key}
          errmsg={errmsg}
          disabled={disabled}
          value={v}
          onChange={(v) => onChange([v])}
        />
      );
    }

    if (field.component == "select") {
      const multiple = ["in", "not in"].includes(operator);
      const v = value as Array<string | number>;
      const errmsg = showError && isEmpty(v) ? "字段必填" : undefined;

      return (
        <SelectComponent
          key={field.key}
          errmsg={errmsg}
          disabled={disabled}
          value={v}
          options={field.options}
          onChange={onChange}
          multiple={multiple}
        />
      );
    }

    if (field.component == "ip") {
      if (operator == "in") {
        let errmsg = isEmpty(value) ? "字段必填" : undefined;
        value?.forEach((i) => {
          if (!isIP(String(i))) errmsg = "IP格式不正确";
          if (i === "") errmsg = "所有内容必填";
        });

        return (
          <ArrayInputComponent
            key={field.key}
            type="string"
            errmsg={showError ? errmsg : undefined}
            disabled={disabled}
            value={value as Array<string>}
            onChange={onChange}
          />
        );
      }
      if (operator == "between") {
        const start = getValueByType<string>(value[0], "string", undefined);
        const end = getValueByType<string>(value[1], "string", undefined);

        let errmsg = undefined;

        if (isUndefined(start)) errmsg = "字段必填";
        else if (!isIP(start)) errmsg = "IP 格式不正确";

        if (isUndefined(end)) errmsg = "字段必填";
        else if (!isIP(end)) errmsg = "IP 格式不正确";

        return (
          <DoubleInputComponent
            type="string"
            key={field.key}
            errmsg={showError ? errmsg : undefined}
            disabled={disabled}
            start={start}
            end={end}
            onChange={onChange}
          />
        );
      }

      const v = getValueByType(value[0], "string", "");
      let errmsg = "";
      if (showError) {
        if (isEmpty(v)) errmsg = "字段必填";

        if (operator == "subnet") {
          if (!isIPv4WithMask(v!) && !isIPv6WithPrefix(v!))
            errmsg = "IP掩码格式不正确";
        } else {
          if (!isIP(v!)) errmsg = "IP格式不正确";
        }
      }

      return (
        <InputComponent
          key={field.key}
          disabled={disabled}
          errmsg={errmsg}
          value={v}
          onChange={(v) => onChange([v])}
        />
      );
    }

    if (field.component == "date") {
      if (operator == "between") {
        const start = getValueByType<string | number>(
          value[0],
          ["string", "number"],
          undefined
        );
        const end = getValueByType<string | number>(
          value[1],
          ["string", "number"],
          undefined
        );

        const errmsg =
          showError && (isEmpty(start) || isEmpty(end))
            ? "字段必填"
            : undefined;

        return (
          <DatePickerRangeComponent
            key={field.key}
            errmsg={errmsg}
            disabled={disabled}
            start={start}
            end={end}
            picker="date"
            onChange={onChange}
          />
        );
      }

      const v = getValueByType<string | number>(
        value[1],
        ["string", "number"],
        undefined
      );

      const errmsg = showError && isEmpty(v) ? "字段必填" : undefined;

      return (
        <DatePickerComponent
          key={field.key}
          errmsg={errmsg}
          disabled={disabled}
          value={v}
          picker="date"
          onChange={(v) => onChange([v!])}
        />
      );
    }

    if (field.component == "datetime") {
      if (operator == "between") {
        const start = getValueByType<string | number>(
          value[0],
          ["string", "number"],
          undefined
        );
        const end = getValueByType<string | number>(
          value[1],
          ["string", "number"],
          undefined
        );

        const errmsg =
          showError && (isEmpty(start) || isEmpty(end))
            ? "字段必填"
            : undefined;

        return (
          <DatePickerRangeComponent
            key={field.key}
            disabled={disabled}
            errmsg={errmsg}
            start={start}
            end={end}
            picker="datetime"
            onChange={onChange}
          />
        );
      }

      const v = getValueByType<string | number>(
        value[1],
        ["string", "number"],
        undefined
      );

      const errmsg = showError && isEmpty(v) ? "字段必填" : undefined;

      return (
        <DatePickerComponent
          key={field.key}
          disabled={disabled}
          errmsg={errmsg}
          value={v}
          picker="datetime"
          onChange={(v) => onChange([v!])}
        />
      );
    }

    if (field.component == "input_array") {
      let errmsg = showError && isEmpty(value) ? "字段必填" : undefined;
      value?.forEach((i) => {
        if (i === "") errmsg = "所有内容必填";
      });

      return (
        <ArrayInputComponent
          key={field.key}
          type="string"
          errmsg={errmsg}
          disabled={disabled}
          value={value as Array<string>}
          onChange={onChange}
        />
      );
    }
  }

  if (field.type == "number") {
    if (field.component == "input") {
      if (operator == "between") {
        const start = getValueByType(value[0], "number", undefined);
        const end = getValueByType(value[1], "number", undefined);
        const errmsg =
          showError && (isEmpty(start) || isEmpty(end))
            ? "字段必填"
            : undefined;
        return (
          <DoubleInputComponent
            type="number"
            key={field.key}
            errmsg={errmsg}
            disabled={disabled}
            start={start}
            end={end}
            onChange={onChange}
          />
        );
      } else {
        const v = getValueByType(value[0], "number", undefined);
        const errmsg = showError && isEmpty(v) ? "字段必填" : undefined;
        return (
          <InputComponent
            key={field.key}
            disabled={disabled}
            type="number"
            errmsg={errmsg}
            value={v}
            onChange={(v) => onChange([v])}
          />
        );
      }
    }

    if (field.component == "select") {
      const multiple = ["in", "not in"].includes(operator);
      const errmsg = showError && isEmpty(value) ? "字段必填" : undefined;
      return (
        <SelectComponent
          key={field.key}
          disabled={disabled}
          value={value as Array<string | number>}
          errmsg={errmsg}
          options={field.options}
          onChange={onChange}
          multiple={multiple}
        />
      );
    }

    if (field.component == "date") {
      if (operator == "between") {
        const start = getValueByType(value[0], "number", undefined);
        const end = getValueByType(value[1], "number", undefined);
        const errmsg =
          showError && (isEmpty(start) || isEmpty(end))
            ? "字段必填"
            : undefined;
        return (
          <DatePickerRangeComponent
            key={field.key}
            disabled={disabled}
            start={start}
            end={end}
            errmsg={errmsg}
            picker="date"
            onChange={(v) => onChange(v)}
          />
        );
      }

      const v = getValueByType(value[0], "number", undefined);
      const errmsg = showError && isEmpty(v) ? "字段必填" : undefined;

      return (
        <DatePickerComponent
          key={field.key}
          disabled={disabled}
          value={v}
          errmsg={errmsg}
          picker="date"
          onChange={(v) => onChange([v!])}
        />
      );
    }

    if (field.component == "datetime") {
      if (operator == "between") {
        const start = getValueByType(value[0], "number", undefined);
        const end = getValueByType(value[1], "number", undefined);
        const errmsg =
          showError && (isEmpty(start) || isEmpty(end))
            ? "字段必填"
            : undefined;
        return (
          <DatePickerRangeComponent
            key={field.key}
            disabled={disabled}
            start={start}
            end={end}
            errmsg={errmsg}
            picker="datetime"
            onChange={(v) => onChange(v)}
          />
        );
      }

      const v = getValueByType(value[0], "number", undefined);
      const errmsg = showError && isEmpty(v) ? "字段必填" : undefined;

      return (
        <DatePickerComponent
          key={field.key}
          disabled={disabled}
          value={v}
          errmsg={errmsg}
          picker="datetime"
          onChange={(v) => onChange([v!])}
        />
      );
    }

    if (field.component == "input_array") {
      let errmsg = showError && isEmpty(value) ? "字段必填" : undefined;
      value?.forEach((i) => {
        if (i === "") errmsg = "所有内容必填";
      });

      return (
        <ArrayInputComponent
          key={field.key}
          errmsg={errmsg}
          type="number"
          disabled={disabled}
          value={value as Array<number>}
          onChange={onChange}
        />
      );
    }
  }

  if (field.type == "boolean") {
    const v = getValueByType(value[0], "boolean", undefined);
    const errmsg = showError && isEmpty(v) ? "字段必填" : undefined;

    return (
      <BooleanComponent
        key={field.key}
        disabled={disabled}
        value={v}
        errmsg={errmsg}
        onChange={(v) => onChange([v])}
      />
    );
  }

  if (typeof field.component == "function") {
    const SelfDefineComponent = field.component;
    return (
      <SelfDefineComponent
        key={field.key}
        showError={showError}
        disabled={disabled}
        type={field.type}
        operators={field.operators}
        value={value}
        onChange={onChange}
      />
    );
  }

  return <div>未识别筛选字段类型</div>;
}
